﻿using SolidWorks.Interop.sldworks;
using SwParaPlatform2.logger;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SwParaPlatform2.dlgRuleConfig
{
    public class RuleConfigModel : IModel
    {
        private static RuleConfigModel instance;

        private readonly ISwParaInterface _commonInterface;

        public event EventHandler SelectCompChanged;
        public event EventHandler SelectDriveTypeChanged;
        public event EventHandler RefreshAllRuleConfigData;
        public event EventHandler OnSetRuleData;
        public event EventHandler OnSelectElementSignal;
        public event EventHandler SelectRowChanged;
        public List<string> DriveTypeList { get; private set; }
        private Dictionary<string, Dictionary<string, object>> dRuleData; //单个参数的规则
        private Dictionary<string, Dictionary<string, object>> dAllRuleConfigData; //所有参数的规则
        private Dictionary<string, object> dNestDict;
        private List<string> DrwList;

        public string sSelectCompName;
        public string sSelectDriveType;
        public string sSelectElement;
        public string sSelectElementFullPath;

        public RuleConfigModel()
        {
            _commonInterface = new SwParaInterface();
            DriveTypeList = new List<string> { "尺寸驱动", "特征压缩", "配合驱动", "零部件", "方程式曲线" };
            dRuleData = new Dictionary<string, Dictionary<string, object>>();
            DrwList = new List<string>();
        }

        public void ClearData(bool bClearAllData)
        {
            SelectCompChanged = null;
            SelectDriveTypeChanged = null;
            sSelectCompName = null;
            sSelectDriveType = null;
            SelectRowChanged = null;
            DrwList = new List<string>();
            dRuleData = new Dictionary<string, Dictionary<string, object>>();
            if (bClearAllData)
            {
                dAllRuleConfigData = new Dictionary<string, Dictionary<string, object>>();
            }
            
        }

        public string SaveData()
        {
            string filePath = XmlHandler.GetFilePath();
            ProcessAllRuleConfigData();

            //为了不重复打开/关闭模型文件，完成UI配置时先缓存UI数据，等完成规则配置时再一起打包
            DataStore.Instance.SaveXmlData(filePath, dAllRuleConfigData);
            return filePath;
        }//存储全局字典

        public void ProcessAllRuleConfigData()
        {
            var updater = SolidWorksPathUpdater.Instance;
            string targetDirectory = DataStore.Instance.sWorkingPath;

            foreach (var outerKvp in dAllRuleConfigData)
            {
                Logger.Instance.Log($"ProcessAllRuleConfigData Key: {outerKvp.Key}");

                // 处理 outerKvp.Value["Rule"] 兼容性
                var ruleDict = GetDictionary(outerKvp.Value, "Rule");

                if (ruleDict != null)
                {
                    foreach (var ruleKvp in ruleDict)
                    {
                        if (ruleKvp.Key == "替换")
                        {
                            var compressDict = ruleKvp.Value as Dictionary<string, object>;
                            if (compressDict != null)
                            {
                                //// 打印压缩字典'sFormula'键对应的值
                                //if (compressDict.TryGetValue("sFormula", out var sFormulaValue))
                                //{
                                //    Logger.Instance.Log($"sFormula: {sFormulaValue}");
                                //}

                                // 处理 lFormulaList 兼容性
                                var lFormulaList = GetList(compressDict, "lFormulaList");

                                if (lFormulaList != null)
                                {
                                    foreach (var element in lFormulaList)
                                    {
                                        if (element is Dictionary<string, object> elementDict)
                                        {
                                            if (elementDict.TryGetValue("Type", out var typeValue))
                                            {
                                                if((string)typeValue == Defines.Type_RepFilePath)
                                                {
                                                    string RepFilePath = (string)elementDict["Value"];
                                                    string NewCompPath = updater.CopyAndModifyReferences(targetDirectory, RepFilePath, "replace");
                                                    elementDict["Value"] = NewCompPath;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // 通用方法：获取字典，兼容嵌套结构
        private Dictionary<string, object> GetDictionary(object parent, string key)
        {
            if (parent is Dictionary<string, object> dict && dict.TryGetValue(key, out var value))
            {
                if (value is Dictionary<string, object> resultDict)
                    return resultDict;

                if (value is Dictionary<string, Dictionary<string, object>> nestedDict)
                    return nestedDict.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value);
            }
            return null;
        }

        // 通用方法：获取列表，兼容嵌套结构
        private List<object> GetList(Dictionary<string, object> parent, string key)
        {
            if (parent.TryGetValue(key, out var value))
            {
                if (value is List<object> resultList)
                    return resultList;

                if (value is List<Dictionary<string, object>> nestedList)
                    return nestedList.Cast<object>().ToList();
            }
            return null;
        }

        public void LoadData()
        {
            string rootElementName = "RuleConfig";
            string drwElementName = "drwConfig";

            var loadedDictionary = XmlHandler.ReadDictionaryFromXml(rootElementName);

            if (loadedDictionary != null)
            {
                SetRuleonfigData(loadedDictionary);
            }

            var drwDictionary = XmlHandler.ReadDictionaryFromXml(drwElementName);

            if (drwDictionary != null)
            {
                foreach (var outerItem in drwDictionary)
                {
                    Logger.Instance.Log($"LoadData - {outerItem.Key}:");
                    foreach (var innerItem in outerItem.Value)
                    {
                        Logger.Instance.Log($"LoadData  {innerItem.Key}: {innerItem.Value}");
                        if (innerItem.Value is List<string> list)
                        {
                            Logger.Instance.Log("  List Values: " + string.Join(", ", list));
                        }
                    }
                }
            }
        }

        public void LoadAllData()
        {
            _commonInterface.LoadAllData();
        }

        public void SetRuleonfigData(Dictionary<string, Dictionary<string, object>> dData)
        {
            if(dData == null)
            {
                dData = new Dictionary<string, Dictionary<string, object>>();
            }
            
            dAllRuleConfigData = dData;
            _OnRefreshAllRuleConfigData();
        } //获取全局字典

        public static RuleConfigModel Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new RuleConfigModel();
                }
                return instance;
            }
        }

        public static void Reset()
        {
            instance = null;
        }

        public void SetRuleData(Dictionary<string, Dictionary<string, object>> dSingleRuleData)
        {
            dRuleData = dSingleRuleData;
            OnSetRuleData?.Invoke();
        }


        public void OnSelectCompName(string sName)
        {
            sSelectCompName = sName;
            OnSelectCompChanged();
        }
        
        public void OnSelectDriveType(string sType)
        {
            sSelectDriveType = sType;
            OnSelectDriveTypeChanged();
        }
        
        public void OnAddRuleConfigData()
        {
            var SingleRuleConfigData = new Dictionary<string, object>
            {
                {"CompName",  sSelectCompName},
                {"DriveType",  sSelectDriveType},
                {"Element",  sSelectElement},
                {"Rule",  dRuleData},
            };
            dAllRuleConfigData[sSelectElementFullPath] = SingleRuleConfigData;
            _OnRefreshAllRuleConfigData();
        }//存储子字典
        
        public void OnSelectElement(string sElement)
        {
            if(DataStore.Instance.dNote_NameData.TryGetValue(sElement, out var sName))
            {
                sSelectElement = (string)sName;
            }
            else
            {
                sSelectElement = sElement;
            }

            SetFullPath(sSelectElement);
            
            List<string> lSearchList = new List<string> { DataStore.Instance.sMainAssemName, sSelectCompName, sSelectElement };
            dNestDict = _commonInterface.GetNestedDictionary(DataStore.Instance.TreeViewData, lSearchList);

            OnSelectElementSignal?.Invoke();

        }

        public void SetFullPath(string sElement)
        {
            var parentChildMap = DataStore.Instance.GetParentChildMap();

            List<string> path = new List<string> { sElement };


            while (parentChildMap.ContainsKey(sElement))
            {
                sElement = parentChildMap[sElement];
                if (sElement != null && sElement != "null")
                {
                    path.Insert(0, sElement);
                }
            }

            sSelectElementFullPath = string.Join(Defines.Comp_Split, path);
            
        }

        public void OnSelectRow(string sPara)
        {
            SetFullPath(sPara);
            try
            {
                Dictionary<string, object> SingleRuleConfigData = dAllRuleConfigData[sSelectElementFullPath];
                sSelectCompName = (string)SingleRuleConfigData["CompName"];
                OnSelectElement(sPara);
                OnSelectRowChanged();
            }
            catch (Exception ex) {
                Logger.Instance.Log($"选中的行{sSelectElementFullPath}不在dAllRuleConfigData内，检查{sPara}是否存在于模型数据节点树中");
                Logger.Instance.Log($"OnSelectRow Error: {ex.Message}");
                var ParentInfo = sPara.Split(new string[] { Defines.Parent_Split }, StringSplitOptions.None);
                string ParaName = ParentInfo[0];
                string ParentName = ParentInfo[1];
                MessageBox.Show($"选中的规则元素：{ParaName}-父节点：{ParentName}不存在！\n请确保基础模型中存在此元素，且对应零部件未被压缩！");

                foreach(string FindKey in dAllRuleConfigData.Keys)
                {
                    if (FindKey.EndsWith(sPara))
                    {
                        sSelectElementFullPath = FindKey;
                        OnSelectRowChanged();
                        break;
                    }
                }
            }
        }

        
        public void OnDelSelectPara()
        {
            if (!string.IsNullOrEmpty(sSelectElementFullPath))
            {
                dAllRuleConfigData.Remove(sSelectElementFullPath);
                _OnRefreshAllRuleConfigData();
            }
        }
        
        public void OnChangeData()
        {
            if (!string.IsNullOrEmpty(sSelectElementFullPath))
            {
                OnAddRuleConfigData();
            }
        }
        
        public void OnSelectRowChanged()
        {
            SelectRowChanged?.Invoke();
        }

        protected virtual void OnSelectCompChanged()
        {
            SelectCompChanged?.Invoke();
        }
        
        protected virtual void OnSelectDriveTypeChanged()
        {
            SelectDriveTypeChanged?.Invoke();
        }
        
        protected virtual void _OnRefreshAllRuleConfigData()
        {
            RefreshAllRuleConfigData?.Invoke();
        }

        public void SetSelectDrwList(List<string> SelectDrwList)
        {
            DrwList = SelectDrwList;
        }

        #region get接口
        public Dictionary<string, object> GetNestDict()
        {
            return dNestDict;
        }
        public List<Dictionary<string, object>> GetFormulaList()
        {
            var formulaList = new List<Dictionary<string, object>>();

            if (dAllRuleConfigData != null && dAllRuleConfigData.TryGetValue(sSelectElementFullPath, out var configData))
            {
                if (configData.TryGetValue("Rule", out var ruleObj))
                {
                    Dictionary<string, Dictionary<string, object>> ruleData = null;
                    if (ruleObj is Dictionary<string, Dictionary<string, object>> nestedRule)
                    {
                        ruleData = nestedRule;
                    }
                    else if (ruleObj is Dictionary<string, object> flatRule)
                    {
                        ruleData = _commonInterface.ConvertToNestedDictionary(flatRule);
                    }

                    if (ruleData != null)
                    {
                        foreach (var rule in ruleData.Values)
                        {
                            if (rule.TryGetValue("lFormulaList", out var formulaListObj))
                            {
                                if (formulaListObj is List<Dictionary<string, object>> list)
                                {
                                    formulaList = list;
                                    break;
                                }
                                else if (formulaListObj is List<object> objList)
                                {
                                    formulaList = objList.Cast<Dictionary<string, object>>().ToList();
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return formulaList;
        }
        public List<string> GetDriveTypeList()
        {
            return DriveTypeList;
        }

        public Dictionary<string, Dictionary<string, object>> GetRuleData()
        {
            return dRuleData;
        }

        public Dictionary<string, Dictionary<string, object>> GetAllRuleConfigData()
        {
            return dAllRuleConfigData;
        }

        public string GetSelectCompName()
        {
            return sSelectCompName;
        }
        
        public string GetSelectDriveType()
        {
            return sSelectDriveType;
        }
        
        public string GetSelectElementFullPath()
        {
            return sSelectElementFullPath;
        }
        
        public string GetSelectElement()
        {
            return sSelectElement;
        }

        public List<string> GetSelectDrwList()
        {
            return DrwList;
        }
        #endregion

        #region 其他接口
        public List<string> GetKeysWithMatchingTypeNames(
            Dictionary<string, Dictionary<string, object>> nestedDictionary, List<string> typeNames)
        {
            var matchingKeys = new List<string>();
            var matchingKeysWithNotes = new List<string>();  // 存储有备注名的元素
            var matchingKeysWithoutNotes = new List<string>();  // 存储没有备注名的元素
            List<string> EquationNames = _commonInterface.GetEquationNames(sSelectCompName);

            if (typeNames == null)
            {
                // 如果 typeNames 为 null，返回所有主字典键
                matchingKeys.AddRange(nestedDictionary.Keys);
                return matchingKeys;
            }

            foreach (var kvp in nestedDictionary)
            {
                var subDictionary = kvp.Value;
                if (subDictionary.ContainsKey("TypeName") && subDictionary["TypeName"] is string typeName)
                {
                    if (typeNames.Contains(typeName))
                    {
                        if(typeName == "Equation")
                        {
                            if (EquationNames.Contains(kvp.Key))
                            {
                                // 对于方程式类型，检查是否有备注名
                                if (DataStore.Instance.dName_NoteData.TryGetValue(kvp.Key, out var sNote))
                                {
                                    matchingKeysWithNotes.Add((string)sNote);
                                }
                                else
                                {
                                    matchingKeysWithoutNotes.Add(kvp.Key);
                                }
                            }
                        }
                        else
                        {
                            // 对于其他类型，优先使用备注名
                            if (DataStore.Instance.dName_NoteData.TryGetValue(kvp.Key, out var sNote))
                            {
                                matchingKeysWithNotes.Add((string)sNote);
                            }
                            else
                            {
                                matchingKeysWithoutNotes.Add(kvp.Key);
                            }
                        }
                    }
                }
            }

            // 合并列表，有备注名的在前面
            matchingKeys.AddRange(matchingKeysWithNotes);
            matchingKeys.AddRange(matchingKeysWithoutNotes);

            return matchingKeys;
        }
        #endregion
    }
}
